#ifndef _CANARY2_HTTP_CONTEXT_H_
#define _CANARY2_HTTP_CONTEXT_H_

#include <system_error>

#include "request.h"
#include "response_builder.h"
#include "recv_request_aw.h"
#include "send_response_aw.h"

#include "../util/concepts.h"
#include "../sys/scheduler_concepts.h"
#include "../coro/task.h" // schedule_aw
#include "../net/tcp_server.h"

namespace wilson::http
{
    template<sys::scheduler Schr>
    class context : public net::tcp_server_context
    {
    public:
        using scheduler_type = Schr;

    public:
        context(net::tcp_server_context&& tcp_ctx, 
                scheduler_type& schr)
            : net::tcp_server_context{ ::std::move(tcp_ctx) }, 
              m_schr{ schr }
        {
        }

        [[nodiscard]] auto send_response(server::response resp, ::std::error_code& ec)
        {
            return schedule_aw(m_schr, send_response_func(
                m_schr.sleeper().suspend_manager(), 
                this->tic_io, // from base class
                ::std::move(resp), 
                &ec
            ));
        }

        [[nodiscard]] auto recv_request()
        {
            return recv_request_aw{
                m_schr.sleeper().suspend_manager(), 
                this->tic_io, // from base class
                chunked_buffer{}
            };
        }

        [[nodiscard]] auto recv_request(::std::error_code& ec)
        {
            return recv_request_aw{
                m_schr.sleeper().suspend_manager(), 
                *this,
                chunked_buffer{}, 
                &ec
            };
        }

    private:
        scheduler_type& m_schr;
    };

    template<typename T>
    concept is_context = util::is_specialization_of<T, http::context>;
}

#endif
